// ignore_for_file: depend_on_referenced_packages

import 'dart:collection';
import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';
import 'package:aitao_flutter/utils/sp_utils.dart';
import 'package:crypto/crypto.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

class OssUtilsV2 {
  static String bucket = SpUtil.getOssBucket();
  static String host = "$bucket.oss-cn-beijing.aliyuncs.com"; //写入你对应的地址
  static String url = 'https://$bucket.oss-cn-hangzhou.aliyuncs.com';

  static Future<String> ossUploadImage(Uint8List imageData,
      {required String fileType, String? directory = "community"}) async {
    //命名
    // String timeStr = DateFormat("yyyyMMdd", 'en').format(DateTime.now());
    String pathName = "img/$directory/app${getRandom(12)}.$fileType";

    //第一步 从服务器获取stsinfo
    Dio dio = Dio();
    // Response e = await dio.get("baseUrl/oss/getStsInfo", //地址自理
    //     queryParameters: Map.from(params));
    // Map<String, dynamic> responseData = jsonDecode(e.data);

    String accessKeyId = SpUtil.getAccessKeyId();
    String accessKeySecret = SpUtil.getAccessKeySecret();
    String securityToken = SpUtil.getSecurityToken();

    String date = getGMTDateString();

    String contentType = 'image/$fileType';
    //签名相关
    //请求头
    SplayTreeMap<String, String> treeMap = SplayTreeMap();
    treeMap["Content-Type".toLowerCase()] = contentType.trim();
    treeMap["Content-MD5".toLowerCase()] = "";
    treeMap["Date".toLowerCase()] = date.trim();
    treeMap["x-oss-security-token".toLowerCase()] = securityToken.trim();
    String headString = "PUT\n";
    treeMap.forEach((key, value) {
      if (key.startsWith("x-oss-")) {
        headString += key;
        headString += ':';
        headString += value;
      } else {
        headString += value;
      }
      headString += '\n';
    });

    String contentString = "/$bucket/$pathName";
    String contentToSign = headString + contentString;

    List<int> key = utf8.encode(accessKeySecret);
    List<int> data = utf8.encode(contentToSign);
    var signaturePre = Hmac(sha1, key).convert(data).bytes;
    //最后一步，将上述所得进行base64 编码
    String signature = base64.encode(signaturePre);
    String signatureA = "OSS $accessKeyId:$signature";
    dio.options.headers["Content-Type"] = 'application/json';
    dio.options.responseType = ResponseType.plain;
    dio.interceptors.add(InterceptorsWrapper(onRequest: (options, handler) {
      options.headers["Authorization"] = signatureA;
      options.headers["Host"] = host;
      options.headers["x-oss-security-token"] = securityToken;
      options.contentType = contentType;
      options.headers["date"] = date;
      // options.headers["Content-Type"] = 'application/json';
      handler.next(options);
    }));
    try {
      // 发送请求
      var resultUrl = "$url/$pathName";
      //必须转成这个类型才可以
      Stream<List<int>> stream = Stream.value(imageData);
      var rep = await dio.put(resultUrl, data: stream);
      // 成功后返回文件访问路径
      debugPrint('上传成功:$rep');
      return "${SpUtil.getImageServer()}/$pathName";
    } catch (e) {
      debugPrint('上传失败:${e.toString()}');
      return '';
    }
  }

  static String getRandom(int num) {
    String alphabet = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
    String left = "";
    for (var i = 0; i < num; i++) {
      left = left + alphabet[Random().nextInt(alphabet.length)];
    }
    return left;
  }

//这个时间要注意
  static String getGMTDateString() {
    var date = DateTime.now();
    date = date.subtract(const Duration(hours: 8));
    return DateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", 'en').format(date);
  }
}
